home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Ham⁄GPS / SoftKiss.src.1.8 Folder / SoftKiss.src.1.8 / core / sfk_core_circular_buffer.c < prev    next >
Text File  |  1993-03-12  |  4KB  |  167 lines

  1. /*
  2.  * SoftKiss - circular text buffer
  3.  * by Aaron Wohl / N3LIW (aw0g+@andrew.cmu.edu) jul 1992
  4.  * 6393 Penn Ave #303
  5.  * Pittsburgh PA, 15206
  6.  * work: (412)-268-5032
  7.  * home: (412)-731-6159
  8.  */
  9.  
  10. #include "sfk_core.h"
  11. #include "sfk_core_private.h"
  12.  
  13. #define CU_WRAP(xx_cu,xx_ptr) \
  14.  do { \
  15.      if(xx_ptr>=(xx_cu)->cu_size) \
  16.          xx_ptr-=(xx_cu)->cu_size; \
  17.  } while(0)
  18.  
  19. /*
  20.  * uninitialize a circular buffer, release any allocated space
  21.  */
  22. void sfk_cu_uninit(sfk_circular_buffer_pt cu)
  23. {
  24.     cu->cu_size=0;
  25.     if(cu->cu_buf!=0)
  26.         sfk_free(cu->cu_buf);
  27.     cu->cu_buf=0;
  28.     cu->cu_read=0;
  29.     cu->cu_write=0;
  30. }
  31.  
  32. /*
  33.  * initialize a circular buffer
  34.  * pass zero for the size to dispose of any allocated memory
  35.  */
  36. void sfk_cu_init(sfk_circular_buffer_pt cu,long max_size)
  37. {
  38.     if(max_size==cu->cu_size)
  39.         return;
  40.     sfk_cu_uninit(cu);
  41.     cu->cu_read=0;
  42.     cu->cu_write=0;
  43.     cu->cu_size=0;
  44.     if(max_size>0)
  45.         cu->cu_buf=sfk_malloc(max_size);
  46.     cu->cu_size=max_size;
  47. }
  48.  
  49.  
  50. /*
  51.  * return max number of bytes that can be written
  52.  */
  53. long sfk_cu_write_size(sfk_circular_buffer_pt cu)
  54. {
  55.     register long chunk=cu->cu_read-cu->cu_write;
  56.     if(chunk>0)
  57.         return sfk_imax(0,chunk-1);
  58.     return sfk_imax(0,(cu->cu_size+chunk)-1);
  59. }
  60.  
  61. /*
  62.  * write data
  63.  */
  64. long sfk_cu_write(sfk_circular_buffer_pt cu,char *put_me,long put_size)
  65. {
  66.     long cu_write=cu->cu_write;
  67.     long put_might_fit=sfk_cu_write_size(cu);
  68.     long put_fits=sfk_imax(0,sfk_imin(put_might_fit,put_size));
  69.     long did_write=put_fits;
  70.     long chunk_size=sfk_imin(did_write,cu->cu_size-cu_write);
  71.     if(chunk_size>0) {
  72.         memcpy(cu->cu_buf+cu_write,put_me,chunk_size);
  73.         cu_write+=chunk_size;
  74.         put_fits-=chunk_size;
  75.         put_me+=chunk_size;
  76.     }
  77.     CU_WRAP(cu,cu_write);
  78.     if(put_fits>0) {
  79.         memcpy(cu->cu_buf+cu_write,put_me,put_fits);
  80.         cu_write+=put_fits;
  81.     }
  82.     CU_WRAP(cu,cu_write);
  83.     cu->cu_write=cu_write;
  84.     return did_write;
  85. }
  86.  
  87. /*
  88.  * return max number of bytes that can be read
  89.  */
  90. long sfk_cu_read_size(sfk_circular_buffer_pt cu)
  91. {
  92.     long cu_write=cu->cu_write;
  93.     if(cu_write<cu->cu_read)
  94.         cu_write+=cu->cu_size;
  95.     return cu_write-cu->cu_read;
  96. }
  97.  
  98. /*
  99.  * read data
  100.  */
  101. long sfk_cu_read(sfk_circular_buffer_pt cu,char *read_me,long read_size)
  102. {
  103.     long read_avail_in_driver=sfk_cu_read_size(cu);
  104.     long read_avail=sfk_imin(read_avail_in_driver,read_size);
  105.     long cu_read=cu->cu_read;
  106.     long chunk_size=sfk_imin(read_avail,(cu->cu_size-cu_read));
  107.     long did_read=read_avail;
  108.     if(chunk_size>0) {
  109.         memcpy(read_me,cu->cu_buf+cu_read,chunk_size);
  110.         cu_read+=chunk_size;
  111.         read_avail-=chunk_size;
  112.         read_me+=chunk_size;
  113.     }
  114.     CU_WRAP(cu,cu_read);
  115.     if(read_avail>0) {
  116.         memcpy(read_me,cu->cu_buf+cu_read,read_avail);
  117.         cu_read+=read_avail;
  118.     }
  119.     CU_WRAP(cu,cu_read);
  120.     cu->cu_read=cu_read;
  121.     return did_read;
  122. }
  123.  
  124. /*
  125.  * memcpy that stops after copying a control character and strips parity
  126.  * returns a count of the characters copied
  127.  */
  128. static long memcpy_break(char *dst,char *src,long count)
  129. {
  130.     register unsigned char ch;
  131.     register unsigned char *usrc=((unsigned char*)src);
  132.     while(--count>=0) {
  133.         ch= *usrc++;
  134.         ch=sfk_MASK_PARITY(ch);    /*mask parity*/
  135.         *dst++ = ch;
  136.         if((ch==0x7f)||((ch<' ')&&(ch!='\t')))
  137.             break;
  138.     }
  139.     return usrc-((unsigned char*)src);
  140. }
  141.  
  142. /*
  143.  * read data stopping on break (control) characters
  144.  */
  145. long sfk_cu_read_line(sfk_circular_buffer_pt cu,char *read_me,long read_size)
  146. {
  147.     long read_avail_in_driver=sfk_cu_read_size(cu);
  148.     long read_avail=sfk_imin(read_avail_in_driver,read_size);
  149.     long cu_read=cu->cu_read;
  150.     long chunk_size;
  151.     long did_read=0;
  152.     long did_chunk;
  153.     while((chunk_size=sfk_imin(read_avail,(cu->cu_size-cu_read)))>0) {
  154.         CU_WRAP(cu,cu_read);
  155.         did_chunk=memcpy_break(read_me,cu->cu_buf+cu_read,chunk_size);
  156.         cu_read+=did_chunk;
  157.         read_avail-=did_chunk;
  158.         read_me+=did_chunk;
  159.         did_read+=did_chunk;
  160.         CU_WRAP(cu,cu_read);
  161.         if(did_chunk!=chunk_size)    /*if we broke due to control char,done*/
  162.             break;
  163.     }
  164.     cu->cu_read=cu_read;
  165.     return did_read;
  166. }
  167.